package com.dongzili.easyes.common.vo;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.List;
import java.util.StringJoiner;

@Getter
@Setter
@Accessors(chain = true)
public class R<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    private Integer code;

    private String message;

    private String token;

    private String traceId;

    private String status;

    private Long count;

    private long times;

    private T data;

    public R(Integer code, String message, String status){
        this.code = code;
        this.message = message;
        this.status = status;
    }

    public R(Integer code, String message, String status, T data){
        this(code,message,status);
        this.status = status;
        this.data = data;
    }
    public R(){}

    public static <T> R<T> success(){
        return new R<>(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getMessage(), ResponseCode.SUCCESS.getStatus());
    }
    public static <T> R<T> success(String message){
        return new R<>(ResponseCode.SUCCESS.getCode(), message, ResponseCode.SUCCESS.getStatus());
    }

    public static <T> R<T> success(T data, Long count){
        if (data instanceof List){
            R<T> r =new R<>(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getMessage(), ResponseCode.SUCCESS.getStatus(),data);
            r.setCount(count);
            return r;
        }
        return new R<>(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getMessage(), ResponseCode.SUCCESS.getStatus(),data);
    }

    public static <T> R<T> success(T data){
        if (data instanceof List){
            R<T> r =new R<>(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getMessage(), ResponseCode.SUCCESS.getStatus(),data);
            r.setCount((long) ((List<?>) data).size());
            return r;
        }
        return new R<>(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getMessage(), ResponseCode.SUCCESS.getStatus(),data);
    }

    public static <T> R<T> success(T data, String message){
        if (data instanceof List){
            R<T> r =new R<>(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getMessage(), ResponseCode.SUCCESS.getStatus(),data);
            r.setCount((long) ((List<?>) data).size());
            return r;
        }
        return new R<>(ResponseCode.SUCCESS.getCode(), message, ResponseCode.SUCCESS.getStatus(),data);
    }

    public static <T> R<T> fail(){
        return new R<>(ResponseCode.FAILURE.getCode(),ResponseCode.FAILURE.getMessage(), ResponseCode.FAILURE.getStatus());
    }

    public static <T> R<T> fail(Integer code, String message, String status){
        return new R<>(code,message, status);
    }

    public static <T> R<T> error(){
        return new R<>(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getMessage(), ResponseCode.ERROR.getStatus());
    }

    public static <T> R<T> error(String msg){
        return new R<>(ResponseCode.ERROR.getCode(), msg, ResponseCode.ERROR.getStatus());
    }

    public static <T> R<T> error(String msg, T data){
        return new R<>(ResponseCode.ERROR.getCode(), msg, ResponseCode.ERROR.getStatus(), data);
    }

    public static <T> R<T> error(ResponseCode response){
        return new R<>(response.getCode(), response.getMessage(), response.getStatus());
    }
//    public static <T> ApiResponse<T> error(ResponseCode response, String msg){
//        return new ApiResponse<>(response.getCode(), msg, response.getStatus());
//    }
    public static <T> R<T> error(ResponseCode response, T data){
        return new R<>(response.getCode(), response.getMessage(), response.getStatus(), data);
    }

    @Override
    public String toString() {
        return (new StringJoiner(", ", R.class.getSimpleName() + "[", "]"))
                .add("code=" + this.code)
                .add("message='" + this.message + "'")
                .add("data=" + this.data)
                .toString();
    }
}
